#include <Lucnx/system.h>
#include <Lucnx/console.h>
#include <Lucnx/debug.h>

extern u32 memory_size;
sysinfo_t *system_info;

// cpuid 指令的函数封装
void get_cpu_id(int fno, void *buf)
{
    u32 eax, ebx, ecx, edx;
    asm volatile
        ("cpuid\n" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(fno));

    // 功能号为 0 的处理: 获取 CPU 厂商名
    if (!fno)
    {
        u32 *cpu_name = buf;
        cpu_name[0] = ebx;
        cpu_name[1] = edx;
        cpu_name[2] = ecx;
    }
}

size_t sys_sysinfo(int nr, void *buf)
{
    switch (nr)
    {
    case INFO_NR_CPU:
        memcpy(buf, system_info->cpu_info, 12);
        ((char *) buf)[12] = '\0'; 
        break;
    case INFO_NR_DISK_COUNT:
        *((u8 *) buf) = system_info->hd_count;
        break;
    case INFO_NR_MEM_SIZE:
        *((u32 *) buf) = system_info->memory_size;
        break;
    }

    return 0;
}

// 初始化内核
void kernel_init()
{
    system_info = kpage_alloc(1); // 获取一页用来存放系统信息
    DEBUGK("system info: %p", system_info);
    system_info->magic = LUCNX_MAGIC;
    get_cpu_id(0, system_info->cpu_info);
    system_info->memory_size = memory_size;

    syscall_init();     // 初始化系统调用
    task_init();        // 初始化任务

    console_switch(1);
    set_interrupt_state(true);
}